package com.nrgedge;

import info.magnolia.cms.beans.config.DefaultVirtualURIMapping;
import info.magnolia.cms.beans.config.URI2RepositoryMapping;
import info.magnolia.context.MgnlContext;
import info.magnolia.module.templatingkit.functions.STKTemplatingFunctions;
import info.magnolia.module.templatingkit.sites.Site;
import info.magnolia.objectfactory.Components;
import info.magnolia.repository.RepositoryConstants;

import javax.jcr.Node;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

/**
 * 
 * Basic VirtualURIMapping class that does a forward to exact matches of fromURI.
 * 
 * Skips mappings that overlap with existing page paths including multi-site page paths.
 * 
 * @author adamgalloway
 *
 */
public class VanityUrlVirtualURIMapping extends DefaultVirtualURIMapping {

	private String configPath;
	private String configPathSite;
	
	@Override
	public MappingResult mapURI(final String uri) {

		final Site site = Components.getComponent(STKTemplatingFunctions.class).site();
		
        if (isValidURI(uri, site)) {
			final MappingResult r = new MappingResult();
			r.setLevel(1);
			r.setToURI("forward:" + this.getToURI());
			return r;
		}

		return null;
	}

	
	private boolean isValidURI(final String uri, final Site site) {
		if (site != null && !configPathSite.equals(site.getName())) {
			return false;
		}
		
		final String fromURI = getFromURI();
		final String requestURI = FilenameUtils.removeExtension(uri);
		
		if (fromURI != null && fromURI.equals(requestURI)) {
			
			// skip if path matches existing page or starts with dot
			if (fromURI.startsWith("/.") || pathExists(fromURI)) {
				return false;
			}
		
			// check site mappings for prefixed urls
			if (site != null) {
				for (URI2RepositoryMapping mapping : site.getMappings().values()) {
					// check website repo mappings
					if (RepositoryConstants.WEBSITE.equals(mapping.getRepository())) {
						final String path = mapping.getHandlePrefix() + fromURI;
						
						// skip existing pages
						if (pathExists(path)){
							return false;
						}
					}
				}
			}
			
			return true;
		} else {
			return false;
		}
		
	}
	
	private boolean pathExists(String path) {
		return getNode(RepositoryConstants.WEBSITE, path) != null;
	}
	
	private Node getNode(String repository, String path) {
		try {
	        return MgnlContext.getJCRSession(RepositoryConstants.WEBSITE).getNode(path);
	    } catch (Exception e) {
	        return null;
	    }
	}

	public String getConfigPath() {
		return configPath;
	}

	public void setConfigPath(String configPath) {
		this.configPath = configPath;
		
		if (configPath != null) {
			this.configPathSite = StringUtils.substringAfterLast(StringUtils.substringBeforeLast(configPath, "/"), "/");
		}
	}

}
